package com.kgc.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.kgc.api.buylimit.TradeOrderApi;
import com.kgc.config.WxpayConfig;
import com.kgc.constant.WxpayConstant;
import com.kgc.util.HttpClient4Util;
import com.kgc.util.WxpayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.TreeMap;

/**
 * @Author：周申宇 <p>
 * @Date:2021/6/16 14:45
 * <p>
 * @Decription: 微信支付业务实现
 */
@Service
@Slf4j
public class WxpayService {

    @Reference(timeout = 30000)
    private TradeOrderApi tradeOrderApi;

    @Autowired
    private WxpayConfig wxpayConfig;

    /**
     * @Auther: 周申宇
     * <p>
     * @Date: 2021/6/16
     * <p>
     * @Description: 封装统一下单参数，返回拼接好的字符串
     */
    public String getWxpayOrderParamsXmlStr(String orderInfo, String body, String ip, int total_fee) throws Exception {
        // 创建一个有序集合，微信统一下单接口要求参数需要字典序列排序
        Map<String, String> params = new TreeMap<>();

        // 应用id
        params.put("appid", wxpayConfig.getAppId());//公众号AppId

        // 商户id
        params.put("mch_id", wxpayConfig.getMchId());//商户ID

        // 随机字符串
        params.put("nonce_str", WxpayUtil.generateNonceStrUseRand(32));

        // 设备号
        params.put("device_info", "WEB");

        // 商品简要描述
        params.put("body", StringUtils.isEmpty(body) ? "huawei" : body);//商品描述

        // 商户订单号
        params.put("out_trade_no", orderInfo);//订单编号

        // 交易金额
        params.put("total_fee", String.valueOf(total_fee));//商品金额

        // 终端ip ip
        params.put("spbill_create_ip", ip);//终端IP

        // 支付结果返回地址
        params.put("notify_url", wxpayConfig.getNotifyUrl());//通知地址

        // 交易类型
        params.put("trade_type", "NATIVE");//交易类型 扫码支付

        // 商品id 支付方式为NATIVE必须传，必须传
        params.put("product_id", WxpayUtil.generateNonceStrUseUUID(6));

        // 签名，一般都是在最后，必须使用上面的所有参数进行的，注意：sign不参与签名
        String sign = WxpayUtil.generateSignature(params, wxpayConfig.getMchKey());
        params.put("sign", sign);


        return WxpayUtil.mapToXml(params);
    }

    public Map<String, String> send2WxpayUnifieldOrder(String wxpayOrderStr) throws Exception {

        // 发送微信官方统一下单,注意：官方要求是post，返回是xml
        String wxpayOrderReturnXmlStr = HttpClient4Util.getResponse4PostByString(wxpayConfig.getOrderUrl(), wxpayOrderStr, "UTF-8");

        // 解析返回的xml
        return WxpayUtil.xmlToMap(wxpayOrderReturnXmlStr);
    }

    /**
     * @Auther: 周申宇
     * <p>
     * @Date: 2021/6/16
     * <p>
     * @Description: 解析微信返回结果
     */
    public String resolveWxpayOrderNotify(String wxpayOrderNotifyXml) throws Exception {
        // 解析xml字符串，获取map集合
        Map<String, String> map = WxpayUtil.xmlToMap(wxpayOrderNotifyXml);
        log.info("++++++++++++++***************");
        //
        if (WxpayConstant.WXPAY_RETURN_SUCCESS.equals(map.get("return_code"))) {
            log.info("-------微信支付异步回调结果。支付成功");

            // 必须要判断签名
            if (WxpayUtil.isSignatureValid(map, wxpayConfig.getMchKey())) {
                log.info("-------微信支付异步回调结果。签名校验成功");
                // 获取订单编号，修改订单状态
                if (!ObjectUtils.isEmpty(map.get("out_trade_no"))) {
                    log.info("更新订单编号:{}", map.get("out_trade_no"));


                    tradeOrderApi.updateOrderInfoByOrderInfoId(map.get("out_trade_no"));
                }

                // 做业务
                return WxpayConstant.WXPAY_RESPONSE_SUCCESS;
            } else {
                log.info("-------微信支付异步回调结果。签名校验失败");
            }
        }
        return WxpayConstant.WXPAY_RESPONSE_FILE;

    }
}
